package com.penglecode.commons.util;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.params.ClientPNames;
import org.apache.http.client.params.CookiePolicy;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.PoolingClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.params.CoreProtocolPNames;
import org.apache.http.params.HttpParams;
import org.apache.http.util.EntityUtils;

public class HttpClientUtils {

	private static final Log Logger = LogFactory.getLog(HttpClientUtils.class);
	
	public static String doGet(String url){
		HttpClient httpClient = null;
		try {
			httpClient = HttpConnectionManager.getHttpClient();
			HttpGet httpGet = new HttpGet(url);
			httpGet.setHeader("Authorization", "E7B3A3C2BF50BD860BC3AE1A60FD49CB");			
			HttpResponse response = httpClient.execute(httpGet);
			HttpEntity httpEntity = response.getEntity();
			if(httpEntity != null){
				return EntityUtils.toString(httpEntity, HttpConnectionManager.DEFAULT_CHARSET);
			}
			return null;
		} catch (Exception e) {
			Logger.error(e.getMessage(), e);
			throw new HttpClientException(e.getMessage(), e);
		}
	}
	
	public static InputStream doGet4Stream(String url){
		HttpClient httpClient = null;
		try {
			httpClient = HttpConnectionManager.getHttpClient();
			HttpGet httpGet = new HttpGet(url);
			HttpResponse response = httpClient.execute(httpGet);
			HttpEntity httpEntity = response.getEntity();
			if(httpEntity != null){
				return httpEntity.getContent();
			}
			return null;
		} catch (Exception e) {
			Logger.error(e.getMessage(), e);
			throw new HttpClientException(e.getMessage(), e);
		}
	}
	
	public static String doPost(String url, Map<String,String> paramMap, boolean paramPostAsJson){
		HttpClient httpClient = null;
		try {
			httpClient = HttpConnectionManager.getHttpClient();
			HttpPost httpPost = new HttpPost(url);
			if(paramMap != null && !paramMap.isEmpty()){
				if(paramPostAsJson){
					String json = JsonUtils.objectToJson(paramMap);
					StringEntity stringEntity = new StringEntity(json.toString());
					stringEntity.setContentEncoding("UTF-8");
					stringEntity.setContentType("application/json");
					httpPost.setEntity(stringEntity);
				}else{
					List<NameValuePair> params = new ArrayList<NameValuePair>();
					for(Map.Entry<String, String> entry : paramMap.entrySet()){
						params.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
					}
					UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(params, HttpConnectionManager.DEFAULT_CHARSET);
					httpPost.setEntity(formEntity);
				}
			}
			HttpResponse response = httpClient.execute(httpPost);
			HttpEntity httpEntity = response.getEntity();
			if(httpEntity != null){
				return EntityUtils.toString(httpEntity, HttpConnectionManager.DEFAULT_CHARSET);
			}
			return null;
		} catch (Exception e) {
			Logger.error(e.getMessage(), e);
			throw new HttpClientException(e.getMessage(), e);
		}
	}
	
	public static InputStream doPost4Stream(String url, Map<String,String> paramMap){
		HttpClient httpClient = null;
		try {
			httpClient = HttpConnectionManager.getHttpClient();
			HttpPost httpPost = new HttpPost(url);
			if(paramMap != null && !paramMap.isEmpty()){
				List<NameValuePair> params = new ArrayList<NameValuePair>();
				for(Map.Entry<String, String> entry : paramMap.entrySet()){
					params.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
				}
				UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(params, HttpConnectionManager.DEFAULT_CHARSET);
				httpPost.setEntity(formEntity);
			}
			HttpResponse response = httpClient.execute(httpPost);
			HttpEntity httpEntity = response.getEntity();
			if(httpEntity != null){
				return httpEntity.getContent();
			}
			return null;
		} catch (Exception e) {
			Logger.error(e.getMessage(), e);
			throw new HttpClientException(e.getMessage(), e);
		}
	}
	
}

class HttpConnectionManager {
	
	private static HttpParams httpParams;
	
	private static ClientConnectionManager connectionManager;  
  
	/**
	 * 默认编码
	 */
	public final static String DEFAULT_CHARSET = "UTF-8";
	
    /** 
     * 最大连接数 
     */  
    public final static int MAX_TOTAL_CONNECTIONS = 100;  
    /** 
     * 连接超时时间 
     */  
    public final static int CONNECT_TIMEOUT = 3000;
    /** 
     * 读取超时时间 
     */  
    public final static int READ_TIMEOUT = 10000;  
	
    static {
    	httpParams = new BasicHttpParams();
    	httpParams.setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
    	httpParams.setParameter(CoreProtocolPNames.HTTP_CONTENT_CHARSET, DEFAULT_CHARSET);
    	httpParams.setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, CONNECT_TIMEOUT);
    	httpParams.setParameter(CoreConnectionPNames.SO_TIMEOUT, READ_TIMEOUT);
    	httpParams.setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.BROWSER_COMPATIBILITY); //设置cookie的兼容性
    	
    	SchemeRegistry registry = new SchemeRegistry();
        registry.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory()));  
        registry.register(new Scheme("https", 443, SSLSocketFactory.getSocketFactory())); 
    	
    	connectionManager = new PoolingClientConnectionManager(registry);
    	((PoolingClientConnectionManager)connectionManager).setMaxTotal(MAX_TOTAL_CONNECTIONS);
    }
    
    public static HttpClient getHttpClient(){
    	return new DefaultHttpClient(connectionManager, httpParams);
    }
    
}

class HttpClientException extends RuntimeException {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	public HttpClientException() {
		super();
	}

	public HttpClientException(String message, Throwable cause) {
		super(message, cause);
	}

	public HttpClientException(String message) {
		super(message);
	}

	public HttpClientException(Throwable cause) {
		super(cause);
	}
	
}